package com.cxs.videoplayer.play;

import com.cxs.videoplayer.api.StatusChangeListener;
import com.cxs.videoplayer.constant.Constants;
import com.cxs.videoplayer.constant.PlayerStatus;
import com.cxs.videoplayer.util.DateUtil;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.window.service.WindowManager;
import ohos.app.Context;
import ohos.global.resource.RawFileDescriptor;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.common.Source;
import ohos.media.player.Player;

import java.io.IOException;

import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT;

public class MPlayer {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00101, "MPlayer");
    private Context context;
    private SurfaceProvider surfaceView;    // 视频窗口
    private Surface surface;        //
    private boolean isSurfaceViewCreate = false;    // 视频窗口是否已创建
    private int startMilliSecond;
    PlayerStatus playerStatus;
    StatusChangeListener statusCallback;
    boolean played = false, prepared =false;

    /**
     * 播放器
     */
    private Player player;
    /**
     * 当前播放文件的路径
     */
    private String filePath;

    private boolean isInitialize = false;

    private MPlayer(Builder builder) {
        this.context = builder.context;
        this.filePath = builder.filePath;
        this.startMilliSecond = builder.startMilliSecond;
        // 创建SurfaceProvider实例
        surfaceView = new SurfaceProvider(this.context);
        // 初始化视频窗口 创建播放容器
        DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(
                MATCH_PARENT, MATCH_PARENT);
        surfaceView.setLayoutConfig(layoutConfig);
        surfaceView.setWidth(MATCH_PARENT);
        surfaceView.setHeight(MATCH_PARENT);
        surfaceView.setVisibility(Component.VISIBLE);
        surfaceView.pinToZTop(false);
        // 不设置窗体透明会挡住播放内容，除非设置pinToZTop为true
        WindowManager.getInstance().getTopWindow().get().setTransparent(true);
        // 设置播放控件的回调函数
        surfaceView.getSurfaceOps().get().addCallback(surfaceCallback);
    }

    // 把PlayerController实例的StatusChangeListener实例传给MPlayer实例的statusCallback
    public void addStatusCallback(StatusChangeListener statusChangeListener) {
        this.statusCallback = statusChangeListener;
    }
    /**
     * 返回视频窗口
     * @return
     */
    public synchronized SurfaceProvider getSurfaceView() {
        return this.surfaceView;
    }

    /**
     * 当前是否正在播放
     * @return
     */
    public synchronized boolean isPlaying() {
        return player.isNowPlaying();
    }

    /**
     * 返回当前播放器
     * @return
     */
    public synchronized Player getPlayer() {
        return this.player;
    }

    public boolean open() {
        return this.open(null);
    }

    public synchronized boolean open(String filePath){
        HiLog.info(LABEL, "open: " + filePath);
        prepared =false;
        if (filePath != null) {
            this.filePath = filePath;
        }
        RawFileDescriptor fd;
        try {
            fd = this.context.getResourceManager().getRawFileEntry(this.filePath).openRawFileDescriptor();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        if (player != null) {
            try {
                player.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
            player.release();
            player = null;
        }
        player = new Player(context);

        Source source = new Source(fd.getFileDescriptor(), fd.getStartPosition(), fd.getFileSize());
        if (!player.setSource(source)) {
            return false;
        }

        player.setPlayerCallback(playerCallback);
        this.prepare();
        return true;
    }

    public synchronized void play() {
        if (player == null) {
            return;
        }
        played = true;
        if (!isPlaying() && prepared) {
            player.play();
            statusCallback.callback(PlayerStatus.PLAY);
        }
    }

    /**
     * 暂停播放
     */
    public synchronized void pause() {
        if (player == null) {
            return;
        }
        if (isPlaying()) {
            player.pause();
            statusCallback.callback(PlayerStatus.PAUSE);
        }
    }

    /**
     * 恢复播放
     */
    public synchronized void resume() {
        if (player == null) {
            return;
        }
        if (!isPlaying()) {
            player.play();
            playerStatus = PlayerStatus.PLAY;
        }
    }

    /**
     * 停止播放
     */
    public synchronized void stop() {
        if (player == null) {
            return;
        }
        if (!isPlaying()) {
            player.stop();
            statusCallback.callback(PlayerStatus.STOP);
        }
    }
    public synchronized String getTitle() {
        if (player == null) {
            return null;
        }
        return this.filePath;
    }
    /**
     * 返回总长度
     * @return
     */
    public synchronized int getDuration() {
        if (player == null) {
            return -1;
        }
        return player.getDuration();
    }
    /**
     * 返回当前播放位置
     * @return
     */
    public synchronized int getPosition() {
        if (player == null) {
            return -1;
        }
        return player.getCurrentTime();
    }

    /**
     * 返回当前播放时间
     * @return
     */
    public synchronized String getPlayerCurrentTime() {
        if (player == null) {
            return "00:00";
        }
        return DateUtil.msToTimeString(getPosition());
    }

    /**
     * 返回总时长
     * @return
     */
    public synchronized String getPlayerDurationTimer() {
        if (player == null) {
            return "00:00";
        }
        return DateUtil.msToTimeString(getDuration());
    }

    Player.IPlayerCallback playerCallback = new Player.IPlayerCallback() {
        @Override
        public void onPrepared() {
            HiLog.info(LABEL, "prepared");
            prepared = true;
            if (played) {
                player.play();
                statusCallback.callback(PlayerStatus.PLAY);
            }
        }

        @Override
        public void onMessage(int i, int i1) {
            // 当收到播放器消息或警报时调用。
            HiLog.info(LABEL, "onMessage");
        }

        @Override
        public void onError(int i, int i1) {

            // 播放出错后的操作
            HiLog.info(LABEL, "onError");
        }

        @Override
        public void onResolutionChanged(int i, int i1) {
            // 视频大小改变时调用
            HiLog.info(LABEL, "onResolutionChanged");

        }

        @Override
        public void onPlayBackComplete() {
            // 播放完成后的操作
            statusCallback.callback(PlayerStatus.COMPLETE);
        }

        @Override
        public void onRewindToComplete() {
            HiLog.info(LABEL, "onRewindToComplete");

        }

        @Override
        public void onBufferingChange(int i) {
            // 缓存百分比更新时调用    i: 缓存百分比
            HiLog.info(LABEL, "onBufferingChange");
        }

        @Override
        public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) {

        }

        @Override
        public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {
            // 当媒体时间连续性中断时调用，例如在回放过程中发生错误时，
            // 回放位置被Player.rewindTo(long)改变，或回放速度突然改变。

        }
    };




    public void prepare() {
        if (!isSurfaceViewCreate) {
            return;
        }
        Thread mThread = new Thread(new Runnable() {
            @Override
            public void run() {

                // 设置视频播放的窗口
                player.setVideoSurface(surface);
                HiLog.info(LABEL, "setVideoSurface");

                player.prepare();
                HiLog.info(LABEL, "prepare");

                if (startMilliSecond > 0) {
                    int microSecond = startMilliSecond * Constants.MICRO_MILLI_RATE;
                    // 设置播放位置
                    player.rewindTo(microSecond);
                }
                statusCallback.callback(PlayerStatus.PREPARE);
            }
        });
        mThread.start();
    }

    private SurfaceOps.Callback surfaceCallback = new SurfaceOps.Callback() {
        @Override
        public void surfaceCreated(SurfaceOps holder) {
            // 在创建Surface时的回调
            isSurfaceViewCreate = true;
            HiLog.info(LABEL, "surfaceCreated");

            surface = holder.getSurface();
            HiLog.info(LABEL, "getSurface");

            prepare();
        }

        @Override
        public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {
        }

        @Override
        public void surfaceDestroyed(SurfaceOps surfaceOps) {
            isSurfaceViewCreate = false;
        }
    };

    public static class Builder {
        private Context context;
        private String filePath;
        private int startMilliSecond = 0;

        public Builder(Context context) {
            this.context = context;
        }

        public Builder setFilePath(String filePath) {
            this.filePath = filePath;
            return this;
        }

        public Builder setStartMilliSecond(int startMilliSecond) {
            this.startMilliSecond = startMilliSecond;
            return this;
        }

        public MPlayer build() {
            return new MPlayer(this);
        }
    }



}
